package org.momo.rpc.retry.impl;

import lombok.extern.slf4j.Slf4j;
import org.momo.rpc.protocol.RpcMessage;
import org.momo.rpc.protocol.RpcResponse;
import org.momo.rpc.retry.RetryPolicy;

import java.util.concurrent.Callable;

@Slf4j
public class FixedRetryPolicy implements RetryPolicy {
    private static final int MAX_RETRY_TIMES = 3;

    private static final int INITIAL_SLEEP_TIME = 3 * 1000;

    @Override
    public RpcMessage<RpcResponse> doRetry(Callable<RpcMessage<RpcResponse>> callable) throws Exception {
        RpcMessage<RpcResponse> resMessage = null;
        int retryTimes = 1;

        while (retryTimes <= MAX_RETRY_TIMES) {
            try {
                resMessage = callable.call();
                return resMessage;
            } catch (Exception exception) {
                log.warn("Rpc call failed, {} retry! reason: {}", retryTimes, exception.getMessage());
                exception.printStackTrace();
                if(retryTimes == MAX_RETRY_TIMES) {
                    throw exception;
                }

                // sleep
                try {
                    Thread.sleep(INITIAL_SLEEP_TIME);
                } catch (InterruptedException ex) {
                    log.warn("Retry interrupted!");
                }

                retryTimes = retryTimes + 1;
            }
        }

        return resMessage;
    }
}
